package com.fahai.common;

import com.fahai.web.vo.SysUserVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.RowMapperResultSetExtractor;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by sky on 16/10/19.
 * 用户权限验证(组权限和角色权限)的自定义类
 */
@Component
public class AuthProvider implements AuthenticationProvider {
	private static final Logger logger = LoggerFactory.getLogger(AuthProvider.class);

    @Resource
    private JdbcTemplate jdbcTemplate;

    //	用户密码验证
	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		String username = authentication.getName();
		String password = authentication.getCredentials().toString();
        try {



            List<SysUserVo> sysUserList =(ArrayList) jdbcTemplate.query("SELECT ur.userid,ur.user_name,ur.user_pw,ur.isvalid,ro.remark, ro.role_name,rm.role,mu.menu_name,mu.menu_url " +
                            "FROM sys_user ur left join user_role ro on ur.role_id=ro.role_id left join role_menu rm on rm.role_id=ro.role_id " +
                            "left join menu mu on mu.menu_id = rm.menu_id where ur.user_name= ? and ur.user_pw= ? ",
                    new Object[]{username, password}, new RowMapperResultSetExtractor(new SysUserMapper()));

            if(!ObjectUtils.isEmpty(sysUserList)) {

                //    登陆认证
                List<SimpleGrantedAuthority> grantedAuths = new ArrayList<SimpleGrantedAuthority>();
                                                          //    权限认证
                grantedAuths.add(new SimpleGrantedAuthority(sysUserList.get(0).getRemark())); // 每个用户只能有一个角色,只需赋值一次,这里后期可能需要getRoleName
                for(SysUserVo suv:sysUserList) {
                    if(suv.getIsvalid()==0){
                        logger.info("<---------------账号被冻结-------------->");
                        grantedAuths=null;
                        return new UsernamePasswordAuthenticationToken("$被冻结$", password, grantedAuths);
                    }
                    // 每个用户可以有多个菜单权限,需多次赋值,这里采用菜单名称+操作权限来设置;
                    grantedAuths.add(new SimpleGrantedAuthority(suv.getMenuName()+"-"+suv.getRole()));
                }
                return new UsernamePasswordAuthenticationToken(username, password, grantedAuths);
            }else{
                logger.info("<---------------账号或密码错误-------------->");
                return null;
//                throw new BadCredentialsException("Bad Credentials");   //账号密码错误
            }
        }catch (DataAccessException e){
            logger.error(e.toString());
            return null;
        }
	}

	@Override
	public boolean supports(Class<?> authentication) {
		return authentication.equals(UsernamePasswordAuthenticationToken.class);
	}

    private class SysUserMapper implements RowMapper {
        @Override
        public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
            Integer userid = rs.getInt("userid");
            String userName = rs.getString("user_name");
            String userPwd = rs.getString("user_pw");
            Integer isvalid = rs.getInt("isvalid");
            String roleName = rs.getString("role_name");
            String roleEn = rs.getString("remark");
            Integer role = rs.getInt("role");
            String menuName = rs.getString("menu_name");
            return new SysUserVo(userid,userName,userPwd,isvalid,roleName,roleEn,role,menuName);
        }
    }
}
